#ifndef SCENE_H
#define SCENE_H

#include "bga/system/ConfigDLL.h"
#include "bga/system/Tree.h"
#include "bga/system/Scoped_Ptr.h"

#include "bga/graphics/SceneNode.h"

#include "bga/math/Matrix.h"

/**
 * \namespace bga
 * \brief API namespace
 */
namespace bga
{

class Camera;
class Drawable;
class Renderer;

/*!
 * \brief A Scene represents a 3D world. TEMPORARY : to remove the need of FBO for a basic scene
 *
 * This class manage all the necessary elements in order to represent different things in a window
 */
class BOARD_HELL_ENGINE BasicScene
{
	public:
		BasicScene();
		virtual ~BasicScene();

        /**
         * \brief Init the scen
         */
		void init();

        /*!
         * \brief Set the root node in the scene
         */
		void setRoot(SceneNode& node);

        /*!
         * \brief Get the camera
         * \return the camera of the scene
         */
		Camera* getCamera();

		/**
		 * \brief Set the camera
		 * \param camera : new camera of the scene
		 */
		void setCamera(Camera* camera);

		/**
		 * \brief change camera dynamically
		 */
		void switchCamera();

        /*!
         * \brief Draw "right eye" by using alternative fbo and camera decal
         */
        void setStereoPass(bool stereoPass);

        /*!
         * \brief Indicate if Scene use stereo (must be same as Game)
         */
        void setUseStereoscopy(bool useStereoscopy);

        /*!
         * \brief Main display loop
         */
		void draw();

        /*!
         * \brief Draw given node
         */
		void drawNode(SceneNode* node);

        /*!
         * \brief Draw list of transparency node after opaque node
         */
		void drawTransparencyNodeList();

		/*!
         * \brief Draw list of node which must be drawn at end
         */
		void drawPostProcessNodeList();

        /*!
         * \brief Used for reflexion, just draw children
         */
        void drawReflectedChildren(SceneNode* node);

    protected:
        /*!
         * \brief Apply states according to inheritance
         */
        void configureCurrentStates(SceneNode* currentSceneNode);

	protected:
        Renderer* renderer;   ///!< Renderer of the objects
        Scoped_Ptr<Camera> camera;       ///!< Camera used
        SceneGraph sceneGraph;///!< SceneGraph
        std::vector<SceneNode*> transparencyNodeList;
        std::vector<SceneNode*> postProcessNodeList;

        /// default Uniform
        Uniform* viewMatrixU;
        Uniform* worldMatrixU;
        Uniform* projectionMatrixU;
        Uniform* alphaU;

        /// current OGL states
        Program* currentProgram;
        FrameBufferObject* currentFbo;
        std::vector<TextureObject*> currentTexture;

        /// stereo parameters
        //float translationStereoMatrix[16];
        Matrix4f translationStereoMatrix;
        bool stereoPass;
        bool useStereoscopy;
};


}

#endif // SCENE_H


